#include <QTextCodec>
#include <QtCore/QCoreApplication>
#include "dryctrlthread.h"
#include "KgGlobalData.h"
#include "io.h"
#include "bmsio.h"
#include <QDir>
#include "tcpmodbdev.h"
#include "unistd.h"
#include "KgBackTrace.h"

/*
2020-10-26     V1.8:   加入通信故障和恢复记录到BA日志.
2020-11-02     V1.9:   加入通用版宏(MASTER_VER)和南都版宏(ND_VER); 加入告警干结点配置(DoID=10).
2020-12-03     V1.10:  加入急停信号采集(DIStrategy=10)
2020-12-23     V1.10:  修改急停信号采集(DIStrategy=11)并通知BA。
2021-02-22     V1.11:  加入消防, 急停, 防雷信号的常闭,常开(默认)配置.
2021-02-26     V1.12:  加入运行灯干结点（DO，ID=6），提取控制汇流开关函数controlHzFz（）。
2021-03-13     V1.12:  实现多个DI同时采集急停急号，防雷信号，消防信号，增加急停策略宏定义。
2021-03-18     V1.12： 急停急号，防雷信号，消防信号确认时间做成配置参数。
2021-03-23to25 V1.12： 通迅故障作为急停处理, 加快急停急号判断,提取函数dealwithConnFailed()
2021-04-17     V1.13:  加入南都版的上电,下电处理
2021-04-30,5-13,5-27:  南都娄底项目,力神珠海项目,万里扬甘肃华庭项目处理,日志增加英文
2021-05-28     V1.14:  加入隔离开关策略(DIStrategy=2)并通知BA。
2021-05-30     V1.15:  修改有实时告警时才去动作告警干结点,不看总状态0x5555,0x1111,0x2222 青岛威控项目
2021-06-22     V1.16:  加入汇流开关反馈配置(DI1AlarmValue=1表示闭合(常用))
2021-07-16     V1.17:  加入操作故障干结点等日志，并根据主版本显示中文或英文
2021-07-17     V1.17:  读到DI发生变化写入到日志，隔离开关状态变化写入到日志
2021-07-18,19  V2.0:   实现读见IO只通过3条命令(DI,DO最多各支持8个)
2021-07-20     V2.0:   完善合闸口分闸口默认是断开的
2021-09-10     V2.1:   加入20:充电接触器驱动 21:放电接触器驱动
2021-09-19     V2.2:   加入检测多个汇流开关的反馈 亿纬尼日尔630A
2021-10-07     V2.3:   加入可以同时控制多个DO口分励脱扣
2021-10-29     V2.4:   加入DO口消防脱扣策略-109 平高大庆项目
2021-11-03     V2.4.1: 修改上传IO数据到通用寄存器(slaveID=100)
2021-11-27     V2.4.2: 加入水浸检测策略(DIStrategy=10)
2021-12-07     V2.4.3: 加入可燃气体检测策略(DIStrategy=12)
2021-12-10     V2.4.4: 加入南都版消防告警时通知后台(pStack->usStackTotAlarm -- Bit8:消防告警)
2021-12-28     V2.4.4: 修改BA不加入可燃气体检测策略,只将信号传给后台
2022-01-06     V2.4.5: 加入读取到可燃气体等信号日志;改刚发生急停时，立马断开汇流开关，不延时
2022-01-07     V2.4.5: 实现按急停按钮可断开汇流开关.
2022-01-09to11 V2.4.6: (1)实现急停和消防时立刻断开汇流开关；(2)断开失败时不断重复;(3)操作成功时再执行一次;(4)配置参数增加RwTimeout,SaveDetaiLog
2022-01-15     V2.4.7: 加入低电压保护时脱扣策略-103 天能尼日利亚项目
2022-01-17     V2.4.8: 增加IOReader类
2022-01-18to19 V2.4.9: 放开接收远程的合闸分闸命令，本程序只做通道;接收EMS的合闸分闸命令(Modbus)
2022-01-25     V2.4.9: 提取hasEmertStopAlarm(),hasEmsHzCmd(),hasEmsFzCmd(),clearEmsCmd()
2022-03-08     V2.4.10:增加getInstallInfo()实时获取安装组数，提取controlOtherFz()函数。
2022-03-27     V2.4.11:增加熔断器配置策略(DIStrategy=13) 南都德升北仑
2022-03-30     V2.4.11:检测隔离开关断开和闭合增加延时
2022-04-06     V2.4.12:增加消防释放信号策略(DIStrategy=14) 南都双一力 (16:37--)
2022-05-22     V2.4.14:IO通信故障关联到测点aExIOModuConnFault
2022-05-25     V2.4.15:修改汇流开关状态传给usDI1,usDI2, 修改BA不配置消防策略时的消防检测与传递
2022-05-27     修改判断急停有误
2022-06-08     增加消防预警信号检测(只记录日志不参与策略)(DIStrategy=22) YW0318
2022-06-30     亿纬0357, 改BA禁放，放电温度上限保护 或 单体电压下限保护时，驱动分闸
2022-07-05     亿纬0357, 改有箱压差，箱温差告警时，禁充，禁放干节点置位
2022-7-11      修改汇流开关反馈通知BA; 增加BMS-EMS通信故障干节点(DOStrategy=22)
2022-8-2       修改支持读取第2个IO模块数据  
2022-11-5      南都华能达板城IO修改，#1，#2BA的IO配置不一样
2022-11-8      加入 23:UPS告警信号 24:门禁告警信号
2022-11-15     通知熔丝熔断告警到BA(FuseStrategy=999)
2022-11-16     熔丝熔断处理 南网梅州项目，江西测试熔丝熔断告警有跳变 // deleted 2022-11-16
2022-11-17     (1)修改产生多余日志： 低电压保护分励脱扣(DO1);
               (2)优化控制汇流开关分闸后再延时300ms, 否则两次控制会连在一起，分闸DO口闭合会太久;
               (3)控制消防脱扣干节点时，加入同时控制汇流开关脱扣;
               (4)分闸成功重复次数由１次改为2次;
               (5)汇流开关合分日志与BA主程序日志重复,汇流开关策略不是200时才输出.// modified 2022-11-18
2022-12-10     增加消防喷洒信号采集(DIStrategy=25)，消防喷洒动作(DOStrategy=23)，消防喷洒脱扣(DOStrategy=110)

2022-12-21     增加消防故障信号采集(DIStrategy=26)

=============================================================================
2022-12-31, 2023-01-01 to 01-03：实现读取界面配置的IO策略 readUserDIDOConfig()

2023-01-05: 实现动态检测用户配置DIDO参数并实时加载, 测试完善

2023-01-06: (1)实现动态检测用户配置的DIDO总个数 (dryctrl.ini中的DIDO个数为最小值，用户界面配置后可变大)
            (2)修改优先读界面配置DIDO参数:readUserDIDOConfig()，再读配置文件:readFileDIDOConfig()
            
2023-01-09: 修改从Rtdb读取串口号(usExIOCommSerialPortNo)，并动态检测是否变化，如变化则退出重启程序.

2023-02-01: DO1和DO2增加支持故障灯，运行灯，汇流开关合闸，汇流开关分闸功能.(不需要修改)

2023-02-03：修改没有IO设备时(串口号为0)不报IO设备通信故障

2023-03-13：整理消防预警(告警),消防启动(喷洒),消防故障; 改消防故障不脱扣火警干节点;
            修改读取DI或DO，都多各支持16个
            
2023-05-04：增加门禁2检测配置(DIStrategy=34) 卧龙储能项目有两个门禁(DI7,DI8)

2023-05-19：增加控制风扇策略(DOStrategy=24)
*/ 

// 2023-06-16 写消防策略
// 2023-06-17 测试消防策略
// 2023-06-23 增加判断各簇QF1开关状态; 记录下EMS控制高压箱分励脱扣日志 
// 2023-06-30 增加普通保护故障时脱扣高压箱断路器 (可以带电流脱扣吗)
// 2023-7-21: 高特版BA usDry5Ctrl 要改为 usDry3Ctrl(断路器接DO3)
// 2023-7-28: 高特运行灯，故障处理 (xnextio.ini  XnExtIO/IsGaoTeVer值为1表示高特版,默认为0) 
// 2023-7-29:修改状态由0x1111,0x2222,0x5555, 0xBBBB等转变为0xAAAA时，才控制高压箱脱扣
// (系统刚启动时虽为故障态，但不会去控制)
// 2023-8-9:修改在有故障时控制脱扣 (系统刚启时除外)
// 2023-10-25:检测到水冷机 1#系统故障,2#系统故障,系统缺水告警,电源故障告警时，控制系统跳机
// 2023-11-9 修改去除485通迅 *************************
// 2023-12-17:增加延时关闭风机(DOStrategy=24);改IO命令控制
// 2023-12-21:V3.1.1加入#2防雷(DOStrategy=108),#2水浸(DOStrategy=110),#2急停信号(DOStrategy=111)
// 2023-12-25:V3.1.1加入BMS就地(DIStrategy=31),BMS远方(DIStrategy=32)
// 2024-1-4:处理中文编码
// 2023-1-6:处理485收到的水浸告警, 消防告警, 消防启动, 消防故障 aEnvTemp[30]to[37]
// 2024-2-3:增加空调机组故障采集(DIStrategy=41),液冷机组故障(DIStrategy=42)
// 2024-2-5:启动风机/充放电指示灯的最小电流改从配置读取(MinChgDchgCur)
// 2024-3-1:消防预警(DOStrategy=22)是否通知BA做成配置参数(XfWarnTellBms:1),默认通知.
// 2024-3-28:修改一些缺馅
// 2024-4-24:修改bug
// 2024-4-26 修改没有汇流开关反馈节点时，也可以自动控制合闸//协鑫板桥44MWh(小屏V3.8.0)潘亚川
// 增加温度驱动干节点策略(DOStrategy=27)// 25 //北京维冠(大屏V2.0.0)邢高威
// 2024-4-27 消防告警等是否分闸做成配置参数(XfWarnFzEnabled=1,XfAlarmFzEnabled=1,WaterAlarmFzEnabled=1)
// 2024-5-1 修改大屏和小屏新屏共用同一个程序(XnBmsIO/OemID:1,2)
// 2024-5-4 修改为远程模式时才匀许合闸 isRemoteMode()
// 2024-5-8 增加通过保持寄存器控制干节点策略(DOStrategy=28, XnBmsIO/KeepRegCtrlPos)
// 2024-6-8  KgGlobalData::ms_pStack->usIsolSwitchStrategy =200
// 2024-6-14 ms_pStack->fStackTemp[47] = usDIState;
// 2024-8-28 xnbmsio增加读取BC的DI配置并产生日志 dealwithBCDIState // 【002003239】安诚液冷工商业
// 2024-09-15 解决与液冷点位冲突
// 2024-10-26 增加BC 断路器脱扣(103)
// 2024-10-27 修改V2.0, V3.8.0对协议消防通迅,水浸通迅的不同处理
// 2024-10-30 增加 ms_faultTkEnabled; //故障时是否脱扣高压箱断路器
// 2024-11-07 增加水浸脱脱交流断路器 瑞欧宝项目V2.0.0
int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

    InitBackTrace(); //先初始化异常处理

	// 设置编码方式
	QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
	//QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
	//QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

	char *publishData = PUBLISH_DATE; // (ACYL)
	printf("XnExtIO Version %d.%d.%d RTDB %d.%d.%d Publish Date (Standard)%s\n",
	APP_VERSION_MAJOR,APP_VERSION_MIDDLE,APP_VERSION_MINOR,
	BAMS_VERSION_MAJOR,BAMS_VERSION_MINOR,BAMS_VERSION_REVISION,publishData);

	//quint16 k = ~(1<<2);
	//quint32 k2 = ~(1<<2);
	//printf("k=========%u,%u\n",k,k2);
	//return 0;
	
    // KgGlobalData::readConfig();

    /*
	QDateTime nowTime = QDateTime::currentDateTime();
	QDateTime other;
	int elapseSec  = other.secsTo(nowTime);
	printf("elapseSec=======%d\n", elapseSec);//other为无效值，得到1995775054，2020-2-22 11：03
    */

	//test save firealarm to db
	/*
	saveFireAlarmToDb(1,32);
	usleep(5 *1000 * 1000); 
	updateAlarmOverToDb();
	*/
	usleep(5 *1000 * 1000); 

	KgGlobalData::ms_isOutputLog = 1;
	int ret = KgGlobalData::InitRtdb(); //初始化Rtdb
	if (ret < 0)
	{
		printf("InitRtdb failed, ret:%d\n", ret);
		return -1;
	}
	KgGlobalData::readConfig();
	/*
	if (isChLang())	   		  
	   saveLogToBaDb(QString("读取IO信息:%1.").arg(KgGlobalData::ms_IOConfigStr));
    else
	   saveLogToBaDb(QString("Read IO Config:%1.").arg(KgGlobalData::ms_IOConfigStr));
	*/
	CIO io;
	CBMSIO newIo;
	
#ifdef BMS_IO_MODEL
/*
#ifdef BMS_XIN_PING
    CBMSIO io;
#else
	CIO io;
#endif
*/
    if (2 == KgGlobalData::ms_hardwareOemID)// new hardware:Nan Bei Shan Ke Ji  // added 2024-5-1
    {
		if (newIo.init() < 0)
		{
			printf("Init newIO Server FAILED, Donot start service");
		}
		else
		{
			newIo.start();
		}
    }
	else // Fan Yi  Ke Ji
	{
		if (io.init() < 0)
		{
			printf("Init IO Server FAILED, Donot start service");
		}
		else
		{
			io.start();
		}
	}
#endif

	DryCtrlThread dryCtrlThread(NULL);
	KgGlobalData::ms_dryThd = &dryCtrlThread;
	
	dryCtrlThread.start();

	TcpModbDev dev;
	// 为2号BA，从1号BA读取消防信号等动环信号 (新疆盛全)
	// 为2号BA, 向1号BA写入从机数据 (楚能华锐)
	if (KgGlobalData::ms_devNo >= 2) // modified 2023-12-30
	{
		writeKgLogfile(QString("********Start TcpModbDev(%1, %2).").arg(g_brotherBaIp).arg(g_brotherBaPort));
		dev.setPara(g_brotherBaIp, g_brotherBaPort);
		//dev.start();
	}
	
	return a.exec();
}
